package capricornus.components.tilelist
{
	import capricornus.actor.utils.Direction;
	import capricornus.components.scrollbar.ScrollBar;
	import capricornus.components.scrollbar.ScrollBarEvent;
	import capricornus.components.scrollbar.ScrollPolicy;
	import capricornus.utils.SpriteUtils;
	
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	
	/**
	 *  
	 * @author kael
	 * 
	 */	
	public class TileList extends Sprite
	{
		private var _w:int = 100;
		private var _h:int = 100;
		
		private var _back:Sprite;
		private var _mask:Shape;
		private var _container:Sprite;
		
		private var _horizonalGap:int = 2;
		private var _verticalGap:int = 2;
		private var _row:int = 0;
		private var _column:int = 0;
		
		private var _rowTileWidth:int = 0;
		
		private var _autoLayout:Boolean = false;
		
		private var _verticalScrollPolicy:int = ScrollPolicy.AUTO;
		private var _verticalScrollBar:ScrollBar;
		
		private var _horizonalScrollPolicy:int = ScrollPolicy.OFF;
		private var _horizonalSrollBar:ScrollBar;
		
		private var _autoRefresh:Boolean = true;
		private var _autoHeight:Boolean = false;
		
		/**
		 * 无竖直方向格子数，取当前排最高元件为当前排竖直间隔
		 * @param row 水平方向格子数, 如果值为0则自动摆放，超过宽度则放置下一排，如果不为0则水平方向等分放置。
		 * 
		 */		
		public function TileList( row:int=0 )
		{
			super();
			_row = row;
			_column = 0;
			init();
		}
		
		private function init():void
		{
			if( _row==0 )
			{
				_autoLayout = true;
			}
			
			_back = SpriteUtils.getSprite( _w, _h );
			_back.alpha = 0;
			addChild( _back );
			
			_container = new Sprite();
			addChild( _container );
			
			_mask = new Shape();
			_mask.graphics.beginFill(0);
			_mask.graphics.drawRect( 0, 0, _w, _h );
			_mask.graphics.endFill();
			addChild( _mask );
			
			_container.mask = _mask;
			
			_verticalScrollBar = new ScrollBar();
			_verticalScrollBar.visible = false;
			_verticalScrollBar.x = _w - _verticalScrollBar.width;
			_verticalScrollBar.addEventListener( ScrollBarEvent.CHANGE, onVerticalScrollChange, false, 0, true );
			
			_horizonalSrollBar = new ScrollBar();
			_horizonalSrollBar.visible = false;
			_horizonalSrollBar.x = 0;
			_horizonalSrollBar.direction = ScrollBar.HORIZONTAL;
			_horizonalSrollBar.y = _h - _horizonalSrollBar.height;
			_horizonalSrollBar.addEventListener( ScrollBarEvent.CHANGE, onHorizonalScrollChange, false, 0, true );
			
			this.addEventListener( MouseEvent.MOUSE_WHEEL, onMouseWheel, false, 0, true );
		}
		
		public function destroy():void
		{
			_verticalScrollBar.removeEventListener( ScrollBarEvent.CHANGE, onVerticalScrollChange );
			_verticalScrollBar.destroy();
			_verticalScrollBar = null;
			
			_horizonalSrollBar.removeEventListener( ScrollBarEvent.CHANGE, onHorizonalScrollChange );
			_horizonalSrollBar.destroy();
			_horizonalSrollBar = null;
			
			this.removeEventListener( MouseEvent.MOUSE_WHEEL, onMouseWheel );
			removeAllItem();
		}
		
		override public function get width():Number
		{
			return _w;
		}
		
		override public function get height():Number
		{
			return _mask.height;
		}
		
		public function get contentHeight():Number
		{
			return _container.height;
		}
		
		public function get length():uint
		{
			return _container.numChildren;
		}
		
		public function get scrollBarWidth():int
		{
			return _verticalScrollBar.width;
		}
		
		public function get row():int
		{
			return _row;
		}
		
		public function get culumn():int
		{
			return _column;
		}
		
		public function set horizonalGap( value:int ):void
		{
			_horizonalGap = value;
			if( _autoRefresh ) refresh();
		}
		
		public function set verticalGap( value:int ):void
		{
			_verticalGap = value;
			if( _autoRefresh ) refresh();
		}
		
		public function set autoRefresh( value:Boolean ):void
		{
			_autoRefresh = value;
			if( _autoRefresh ) refresh();
		}
		
		/**
		 *  
		 * @param value 每个格子的宽度，默认为0。自动摆放时此值亦有效
		 * 
		 */		
		public function set rowTileWidth( value:int ):void
		{
			_autoLayout = true;
			if( _rowTileWidth != value )
			{
				_rowTileWidth = value;
				refresh();
			}
		}
		
		/**
		 * 设置滚动条位置， 范围(0~1) 
		 * @param value
		 * 
		 */		
		public function set proportion( value:Number ):void
		{
			_verticalScrollBar.proportion = value;
		}
		
		/**
		 * 竖直滚动条显示方式，默认是ScrollPolicy.AUTO
		 * @param value
		 * 
		 */		
		public function set verticalScrollPolicy( value:int ):void
		{
			if( _verticalScrollPolicy != value )
			{
				_verticalScrollPolicy = value;
				if( _verticalScrollPolicy==ScrollPolicy.ON )
				{
					addChild( _verticalScrollBar );
					_verticalScrollBar.visible = true;
					resetScrollBar();
				}
				else if( _verticalScrollPolicy==ScrollPolicy.OFF )
				{
					if( _verticalScrollBar.visible )
					{
						removeChild( _verticalScrollBar );
						_verticalScrollBar.visible = false;
					}
					_container.y = 0;
				}
				else if( _verticalScrollPolicy==ScrollPolicy.AUTO )
				{
					resetScrollBar();
				}
			}
		}
		
		/**
		 * 水平滚动条的显示方式，默认是ScrollPolicy.OFF; 
		 * @param value
		 * 
		 */		
		public function set horizonalScrollPolicy( value:int ):void
		{
			if( _horizonalScrollPolicy != value )
			{
				_horizonalScrollPolicy = value;
				if( _horizonalScrollPolicy==ScrollPolicy.ON )
				{
					addChild( _horizonalSrollBar );
					_horizonalSrollBar.visible = true;
					resetScrollBar();
				}
				else if( _horizonalScrollPolicy==ScrollPolicy.OFF )
				{
					if( _horizonalSrollBar.visible )
					{
						removeChild( _horizonalSrollBar );
						_horizonalSrollBar.visible = false;
					}
					_container.x = 0;
				}
				else if( _horizonalScrollPolicy==ScrollPolicy.AUTO )
				{
					resetScrollBar();
				}
			}
		}
		
		/**
		 * 自动高度 
		 * @param value 默认是false，如果为true，verticalScrollPolicy将成OFF
		 * 
		 */	
		public function set autoHeight( value:Boolean ):void
		{
			_autoHeight = value;
			if( _autoHeight )
			{
				verticalScrollPolicy = ScrollPolicy.OFF;
			}
			else
			{
				verticalScrollPolicy = ScrollPolicy.ON;
			}
		}
		
		public function setLocation( x:int, y:int ):void
		{
			this.x = x;
			this.y = y;
		}
		
		/**
		 *  
		 * @param w 滚动条位置在w里面
		 * @param h
		 * 
		 */		
		public function setSize( w:int, h:int ):void
		{
			_w = w;
			_h = h;
			_container.mask = _mask;
			_back.width = w;
			_back.height = h;
			_mask.width = w;
			_mask.height = h;
			_verticalScrollBar.x = _w - _verticalScrollBar.width;
			_verticalScrollBar.setSize( 0, _h );
			
			_horizonalSrollBar.y = _h - _horizonalSrollBar.height;
			_horizonalSrollBar.setSize( _w, 0 );
		}
		
		public function addItem( item:DisplayObject ):void
		{
			_container.addChild( item );
			if( _autoRefresh ) this.refresh();
		}	
		
		public function addItemAt( item:DisplayObject, index:int ):void
		{
			if( index > _container.numChildren ) _container.addChild( item );
			else _container.addChildAt( item, index );
			
			if( _autoRefresh ) this.refresh();
		}
		
		public function removeItem( item:DisplayObject ):DisplayObject
		{
			_container.removeChild( item );
			destroyItem( item );
			
			if( _autoRefresh ) this.refresh();
			
			return item;
		}
		
		public function removeItemAt( index:int ):DisplayObject
		{
			var dis:DisplayObject =  _container.removeChildAt( index );
			destroyItem( dis );
			
			if( _autoRefresh )
			{
				this.refresh();
			}
			return dis;
		}
		
		public function getItemIndex( item:DisplayObject ):int
		{
			return _container.getChildIndex( item );
		}
		
		public function getItemAt( index:uint ):DisplayObject
		{
			return _container.getChildAt( index );
		}
		
		public function removeAllItem():void
		{
			while( _container.numChildren > 0 ) destroyItem( _container.removeChildAt(0) );
			_container.y = 0;
			_container.x = 0;
			resetScrollBar();
		}
		
		private var _isDestroyOnRemove:Boolean = false;
		public function set isDestroyOnRemove( value:Boolean ):void
		{
			_isDestroyOnRemove = value;
		}
		
		protected function destroyItem( item:DisplayObject ):void
		{
			if( _isDestroyOnRemove && item.hasOwnProperty( "destroy" ) )
			{
				(item as Object).destroy();
			}
		}
		
		public function refresh():void
		{
			var i:int;
			var len:int = _container.numChildren;
			var w:int = 0;
			var y:int = 0;
			var h:int = 0;
			var perWidth:int = _rowTileWidth>0?_rowTileWidth:(_w / _row);
			_column = len>0?1:0;
			var rc:int = 0;
			for( i=0; i<len; i++ )
			{
				var dis:DisplayObject = _container.getChildAt(i);
				var b:Boolean = false;
				if( _row > 0 )
				{
					if( rc >= _row )
					{
						b = true;
					}
				}
				if( b || (w > 0 && w + dis.width > _w) )
				{
					y += (h + _verticalGap);
					h = 0;
					w = 0;
					rc = 0;
					_column++;
				}
				dis.y = y;
				if( _autoLayout )
				{
					dis.x = int(w);
					w += ((_rowTileWidth>0?_rowTileWidth:dis.width) + _horizonalGap);
				}
				else
				{
					dis.x = int(w);
					w += (perWidth);
				}
				if( dis.height > h )
				{
					h = dis.height;
				}
				rc++;
			}
			if( _autoHeight )
			{
				_mask.height = _container.height;
			}
			resetScrollBar();
		}
		
		private function onMouseWheel( e:MouseEvent ):void
		{
			if( _container.height > _h && _verticalScrollPolicy != ScrollPolicy.OFF )
			{
				_verticalScrollBar.scrollPosition -= e.delta*2;
			}
			else if( _container.width > _w && _horizonalScrollPolicy != ScrollPolicy.OFF )
			{
				_horizonalSrollBar.scrollPosition -= e.delta*2;
			}
		}
		
		private function onVerticalScrollChange( e:ScrollBarEvent ):void
		{
			_container.y = int(e.data * (_h-(_horizonalSrollBar.visible?_horizonalSrollBar.height:0) - _container.height));
		}
		
		private function onHorizonalScrollChange( e:ScrollBarEvent ):void
		{
			_container.x = int(e.data * (_w-(_verticalScrollBar.visible?_verticalScrollBar.width:0) - _container.width));
		}
		
		private function resetScrollBar():void
		{
			if( _verticalScrollPolicy==ScrollPolicy.OFF ) 
			{
				_container.y = 0;
			}
			else 
			{
				if( _container.height > _h )
				{
					if( _verticalScrollBar.visible==false )
					{
						addChild( _verticalScrollBar );
					}
					_verticalScrollBar.visible = true;
					_verticalScrollBar.setViewInfo( _h, _container.height );
				}
				else if( _verticalScrollPolicy==ScrollPolicy.ON )
				{
					_verticalScrollBar.setViewInfo( 0, 0 );
				}
				else if( _verticalScrollPolicy==ScrollPolicy.AUTO )
				{
					_verticalScrollBar.setViewInfo( 0, 0 );
					_verticalScrollBar.visible = false;
				}
			}
			if( _horizonalScrollPolicy==ScrollPolicy.OFF )
			{
				_container.x = 0;
			}
			else
			{
				if( _container.width > _w )
				{
					if( _horizonalSrollBar.visible==false )
					{
						addChild( _horizonalSrollBar );
					}
					_horizonalSrollBar.visible = true;
					_horizonalSrollBar.setViewInfo( _w, _container.width );
				}
				else if( _horizonalScrollPolicy==ScrollPolicy.ON )
				{
					_horizonalSrollBar.setViewInfo( 0, 0 );
				}
				else if( _horizonalScrollPolicy==ScrollPolicy.AUTO )
				{
					_horizonalSrollBar.setViewInfo( 0, 0 );
					_horizonalSrollBar.visible = false;
				}
				
				if( _horizonalSrollBar.visible && _verticalScrollBar.visible )
				{
					_horizonalSrollBar.setSize( _w-_verticalScrollBar.width, 0 );
				}
			}
		}
	}
}




